package com.ztesoft.web.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

import com.ztesoft.framework.log.ZTEsoftLogManager;

/**
 * 运用Ganymed-ssh2开源组件实现ssh协议采集工具类
 * 
 * 
 */
public final class SSHGanymedUtil {

	/**
	 * 日志信息
	 */
	private static final ZTEsoftLogManager LOGGER = ZTEsoftLogManager.getLogger(SSHGanymedUtil.class);

	/**
	 * 登陆ip
	 */
	private String hostname;

	/**
	 * 采集端口
	 */
	private int port;

	/**
	 * ssh用户
	 */
	private String username;

	/**
	 * ssh口令
	 */
	private String password;

	/**
	 * 性能指标采集任务
	 */
	private long taskId;

	/**
	 * ssh采集会话
	 */
	private Connection connection;

	/**
	 * 构造函数
	 * 
	 * @param _hostname
	 *            登陆ip
	 * @param _port
	 *            端口
	 * @param _username
	 *            ssh用户
	 * @param _password
	 *            ssh口令
	 */
	public SSHGanymedUtil(String _hostname, int _port, String _username,
			String _password) {
		this.hostname = _hostname;
		this.port = _port;
		this.username = _username;
		this.password = _password;
	}

	/**
	 * 构造函数
	 * 
	 * @param _hostname
	 *            登陆ip
	 * @param _port
	 *            端口
	 * @param _username
	 *            ssh用户
	 * @param _password
	 *            ssh口令
	 * @param id
	 *            性能指标id
	 */
	public SSHGanymedUtil(String _hostname, int _port, String _username,
			String _password, Long id) {
		this(_hostname, _port, _username, _password);
		this.taskId = id;
		LOGGER.info("/util/SSHGanymedUtil/_" + id);
	}

	/**
	 * 登陆SSH服务器
	 * 
	 * @throws Exception
	 */
	public void login() throws Exception {
		LOGGER.info("start task id is " + taskId);

		// 建立连接
		connection = new Connection(hostname, port);
		try {
			// 连接上
			connection.connect();

			// 进行校验
			boolean isAuthenticated = connection.authenticateWithPassword(
					username, password);

			LOGGER.info("isAuthenticated = " + isAuthenticated);
			if (isAuthenticated == false)
				throw new IOException("Authentication failed.");

		} catch (Exception e) {
			LOGGER.error(e);
			throw new Exception("UserOrPasswordError");
		}
	}

	/**
	 * 发送shell命令并获取执行结果
	 * 
	 * @param command
	 *            发送执行的命令
	 * @return 返回命令的执行结果
	 */
	public String execCommand(final String command) {
		LOGGER.info("start exexCommand");
		final StringBuilder sb = new StringBuilder(256);
		// 连接的通道
		Session sess = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader br = null;
		try {
			// 创建session
			sess = connection.openSession();

			// 这句非常重要，开启远程的客户端
			sess.requestPTY("vt100", 80, 24, 640, 480, null);

			// 开启后睡眠4秒
			Thread.sleep(4000);

			// 开启终端
			// sess.startShell();
			// 执行命令
			sess.execCommand(command);

			// 起始时间,避免连通性陷入死循环
			long start = System.currentTimeMillis();
			// // 增加timeOut时间
			// sess.waitForCondition(ChannelCondition.TIMEOUT, 5000);
			inputStreamReader = new InputStreamReader(new StreamGobbler(sess.getStdout()));
			br = new BufferedReader(inputStreamReader);

			char[] arr = new char[512];
			int read;

			int i = 0;

			while (true) {
				// 将结果流中的数据读入字符数组
				read = br.read(arr, 0, arr.length);

				// 推延5秒就退出[针对连通性测试会陷入死循环]
				if (read < 0 || (System.currentTimeMillis() - start) > 5000)
					break;

				// 将结果拼装进StringBuilder
				sb.append(new String(arr, 0, read));
				i++;
			}

			LOGGER.info("ExitCode: " + sess.getExitStatus() + "i = " + i);

		} catch (Throwable e) {
			LOGGER.error(e);
		} finally {
			if (inputStreamReader != null) {
				try {
					inputStreamReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (br !=null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			// 关闭通道
			if (sess != null)
				sess.close();
		}
		return sb.toString();
	}

	/**
	 * 关闭ssh连接
	 */
	public void closeConnection() {
		LOGGER.info("end task id is " + taskId + "disconnet");
		if (connection != null)
			connection.close();
	}

	public String getHostname() {
		return hostname;
	}

	public void setHostname(String hostname) {
		this.hostname = hostname;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		char[] c = new char[3072];

		for (int i = 0; i < c.length; i++) {
			c[i] = 'a';
		}

		String s = new String(c, 0, 3072);
		System.out.println(s);

	}

}

